using UnityEngine;

using SMGCore;
using SMGCore.EventSys;
using Voxels.Events;
using Cysharp.Threading.Tasks;

namespace Voxels {
	public sealed class ChunkRenderer : PoolItem {
		public MeshRenderer MeshRenderer           = null;
		public MeshFilter   MeshFilter             = null;
		public MeshCollider Collider;

		Chunk _targetChunk   = null;

		public Chunk Chunk => _targetChunk;

		public void Setup(Chunk targetChunk) {
			EventManager.Subscribe<Event_ChunkMeshUpdate>(this, OnChunkUpdate);
			_targetChunk = targetChunk;
			UpdateRenderer();
			gameObject.SetActive(true);
		}

		public override void DeInit() {
			EventManager.Unsubscribe<Event_ChunkMeshUpdate>(OnChunkUpdate);
			DeInitRenderer();
			_targetChunk = null;
		}

		void DeInitRenderer() {
			MeshFilter.mesh                   = null;
		}

		void UpdateRenderer() {
			DeInitRenderer();
			MeshFilter.mesh  = _targetChunk.OpaqueCollidedMesh.Mesh;
		}

		async void OnChunkUpdate(Event_ChunkMeshUpdate e) {
			if ( e.UpdatedChunk == _targetChunk ) {
				UpdateRenderer();
				await UpdateCollider(e.UpdatedChunk.OpaqueCollidedMesh.Mesh);
			}
			
		}

		async UniTask UpdateCollider(Mesh mesh) {
			var sw = new System.Diagnostics.Stopwatch();
			sw.Start();
			var meshInstance = mesh.GetInstanceID();
			await UniTask.SwitchToThreadPool();
			Physics.BakeMesh(meshInstance, false);
			await UniTask.SwitchToMainThread();
			Collider.sharedMesh = mesh;
		}
		

		private void OnDestroy() {
			EventManager.Unsubscribe<Event_ChunkMeshUpdate>(OnChunkUpdate);
		}
	}
}
